#ifndef __QUERY_SET_H__
#define __QUERY_SET_H__

#include "alignerOutput.h"

typedef unsigned int word_t;

class QuerySet {
public:
	unsigned long numQuery;
	int numWordPerQuery;
	int readLength;
	word_t* query;
	bool isTwoStrand;	//if it is two strand, the first half is positive, 
				//and the second half is negative

	//these are just three pointers
	char* read;
	char* qscore;
	int* rid;	//read id

	//temp buffer
	char revRead[1000];
public:
	QuerySet() {
		query = NULL;
	}

	~QuerySet() {
		if(query)
			delete[] query;
	}

	inline const char* getRead(const int qid) {
/*
		if(qid < numQuery/2) { //+ strand
			return read + readLength*qid;
		} else {	// - strand
			reverse_complement(revRead, read + readLength*getRid(qid), readLength);
			return revRead;
		}
*/
		return read + readLength*qid;
	}

	//generate reads for both strands!
	inline void setRead(const char* i_read, const int i_readLength, const int i_numRead) {
		assert(i_readLength == readLength);
		assert(i_numRead == numQuery/2);
		read = new char[readLength*numQuery];

		//positive strand
		memcpy(read, i_read, sizeof(char)*readLength*numQuery/2);

		//negative strand
		for(unsigned int rid = numQuery/2; rid < numQuery; rid++) {
			reverse_complement(read + rid*readLength, 
					read + readLength*(rid - numQuery/2), readLength);
		}
	}

	//suppose two strands, input the query id, return the read id
	inline unsigned long getRid(const unsigned long qid) const {
		return (qid >= numQuery/2) ? (qid - numQuery/2) : qid;
	}

	inline unsigned int numRead() const {
		return numQuery/2;
	}

	void alloc(	const unsigned long i_numQuery,
			const int i_numWordPerQuery, 
			const int i_readLength, 
			bool i_isTwoStrand) {
		numQuery = i_numQuery;
		numWordPerQuery = i_numWordPerQuery;
		readLength = i_readLength;
		query = new word_t[numQuery*numWordPerQuery];
		isTwoStrand = i_isTwoStrand;
	}

};


//used to record the number of alignments for a read (not QUERY!)
class ReadSetStatus {
public:
	unsigned int numRead;
	int* numAlignPerRead;
	ReadSetStatus(const unsigned int i_numRead) :
		numRead(i_numRead) {
		numAlignPerRead = new int[numRead];
	}

	void clear() {
		for(int i = 0; i < numRead; i++) {
			numAlignPerRead[i] = 0;
		}
	}

	~ReadSetStatus() {
		delete[] numAlignPerRead;
	}
};

#endif /*__QUERY_SET_H__*/
